package com.example.demo.ctrl.config.threadTest.testMap;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * map容器测试，面试必备：HashMap、Hashtable、ConcurrentHashMap的原理与区别：
 * https://www.cnblogs.com/heyonggang/p/9112731.html
 * https://blog.csdn.net/sinbadfreedom/article/details/80375048
 */
public class TsetMap {

    public static void main(String[] args) {
        /** 全局HashMap*/
        HashMap<Integer, Integer> hashMap = new HashMap();
        hashMap.put(0, 0);

        /** 多线程编辑100次*/
        for (int i = 0; i < 100; i++) {
            new Thread(new EditThread(hashMap)).start();
        }

        /** 读取线程*/
        new Thread(new ReadThread(hashMap)).start();
        /** 输出最终结果*/
        System.out.println("Demo1 main value " + hashMap.get(0));


//多次运行，输出的结果可能不一致。这样说明多线程修改ConcurrentHashMap中的数据，不能保证多线程同步。需要进行加锁或者其他能达到线程同步的方式配合使用。
        /** 全局ConcurrentHashMap*/
        ConcurrentHashMap<Integer, Integer> hashMap2 = new ConcurrentHashMap();
        hashMap2.put(0, 0);

        /** 多线程编辑100次*/
        for (int i = 0; i < 100; i++) {
            new Thread(new EditThread1(hashMap2)).start();
        }

        /** 读取线程*/
        new Thread(new ReadThread1(hashMap2)).start();
        /** 输出最终结果*/
        System.out.println("Demo2 main value " + hashMap2.get(0));
    }
}

/**
 * hashMap写线程
 */
class EditThread implements Runnable {

    Map<Integer, Integer> hashMap;

    public EditThread(Map<Integer, Integer> hashMap) {
        this.hashMap = hashMap;
    }

    @Override
    public void run() {
        hashMap.put(0, hashMap.get(0) + 1);
    }
}

/**
 * hashMap读线程
 */
class ReadThread implements Runnable {

    Map<Integer, Integer> hashMap;

    public ReadThread(Map<Integer, Integer> hashMap) {
        this.hashMap = hashMap;
    }

    @Override
    public void run() {
        System.out.println("读value " + hashMap.get(0));
    }
}


/**
 * ConcurrentHashMap写线程
 */
class EditThread1 implements Runnable {

    ConcurrentHashMap<Integer, Integer> hashMap;

    public EditThread1(ConcurrentHashMap<Integer, Integer> hashMap) {
        this.hashMap = hashMap;
    }

    @Override
    public void run() {
        hashMap.put(0, hashMap.get(0) + 1);
    }
}

/**
 * ConcurrentHashMap读线程
 */
class ReadThread1 implements Runnable {

    ConcurrentHashMap<Integer, Integer> hashMap;

    public ReadThread1(ConcurrentHashMap<Integer, Integer> hashMap) {
        this.hashMap = hashMap;
    }

    @Override
    public void run() {
        System.out.println("读value2 " + hashMap.get(0));
    }
}